package com.sample.service.impls;

import java.math.BigDecimal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sample.dto.UserDTO;
import com.sample.entity.User;
import com.sample.exception.AmountLackException;
import com.sample.mapper.UserMapper;
import com.sample.service.UserService;
import com.swak.annotation.DynamicSource;
import com.swak.annotation.FluxService;
import com.swak.annotation.Tcc;
import com.swak.service.BaseService;
import com.swak.utils.BigDecimalUtils;

/**
 * 描述
 * 
 * @author Auto Generator
 * @date 2022-04-21T20:45:31.165333600
 */
@FluxService
@Service("swakUserService")
public class UserServiceImpl extends BaseService<User, Long> implements UserService {

	@Autowired
	private UserMapper userMapper;

	@Tcc(confirm = "bookConfirm", cancel = "bookCancel")
	@DynamicSource(value = "User")
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	@Override
	public UserDTO book(UserDTO user) {

		/*
		 * 锁住当前用户
		 */
		User lockUser = userMapper.lock(user.getId());

		/*
		 * 校验金额
		 */
		BigDecimal remainAmount = BigDecimalUtils.sub(lockUser.getAccount(), user.getAccount());
		if (BigDecimalUtils.smallerThenZero(remainAmount)) {
			throw new AmountLackException();
		}

		/*
		 * 修改剩余的金额和冻结的金额
		 */
		User.of().setAccount(remainAmount).setFreeze(BigDecimalUtils.add(user.getAccount(), lockUser.getFreeze()))
				.setId(lockUser.getId()).updateSelective();

		/*
		 * 返回最新的数据
		 */
		return UserDTO.convert(userMapper.get(user.getId()));
	}

	@DynamicSource(value = "User")
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void bookConfirm(UserDTO user) {

		/*
		 * 锁住当前用户
		 */
		User lockUser = userMapper.lock(user.getId());

		/*
		 * 扣除冻结的金额
		 */
		User.of().setFreeze(BigDecimalUtils.sub(lockUser.getFreeze(), user.getAccount())).setId(user.getId())
				.updateSelective();

	}

	@DynamicSource(value = "User")
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void bookCancel(UserDTO user) {

		/*
		 * 锁住当前用户
		 */
		User lockUser = userMapper.lock(user.getId());

		/*
		 * 扣除冻结的金额
		 */
		User.of().setFreeze(BigDecimalUtils.sub(lockUser.getFreeze(), user.getAccount()))
				.setAccount(BigDecimalUtils.add(lockUser.getAccount(), user.getAccount())).setId(user.getId())
				.updateSelective();
	}
}
